home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / HACK.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  29KB  |  1,226 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* NetHack may be freely redistributed.  See license for details. */
  3.  
  4. #include "hack.h"
  5.  
  6. #if defined(UNIX) && !defined(LINT)
  7. static    const char    SCCS_Id[] = "@(#)hack.c    3.0\t89/11/20";
  8. #endif
  9.  
  10. STATIC_DCL int NDECL(moverock);
  11. #ifdef SINKS
  12. STATIC_DCL void NDECL(dosinkfall);
  13. #endif
  14.  
  15. #ifdef OVL1
  16. static boolean FDECL(is_edge,(XCHAR_P,XCHAR_P));
  17. static boolean FDECL(bad_rock,(XCHAR_P,XCHAR_P));
  18. #endif /* OVL1 */
  19.  
  20. #ifdef OVLB
  21.  
  22. /* called on movement:
  23.     1. when throwing ball+chain far away
  24.     2. when teleporting
  25.     3. when walking out of a lit room
  26.  */
  27. void
  28. unsee() {
  29.     register xchar x,y;
  30.     register struct rm *lev;
  31.  
  32.     if(seehx){
  33.         seehx = 0;
  34.     } 
  35.     /*
  36.      *  Erase surrounding positions if needed.  We don't need to do this
  37.      *  if we are blind, since we can't see them anyway.  This removes the
  38.      *  pl6 bug that makes monsters disappear if they are next to you if
  39.      *  you teleport while blind and telepathic.
  40.      */
  41.     else if(!Blind)
  42.         for(x = u.ux-1; x < u.ux+2; x++)
  43.             for(y = u.uy-1; y < u.uy+2; y++) {
  44.             if(!isok(x, y)) continue;
  45.             lev = &levl[x][y];
  46.             if(!lev->lit && lev->scrsym == ROOM_SYM) {
  47.             lev->scrsym = STONE_SYM;
  48.             lev->new = 1;
  49.             on_scr(x,y);
  50.             }
  51.             }
  52. }
  53.  
  54. /* called:
  55.     in apply.c:  seeoff(0)    - when taking a picture of yourself
  56.                 - when donning a blindfold
  57.     in do.c:     seeoff(0)    - blind after drinking potion
  58.     in do.c:     seeoff(1)    - go up or down the stairs
  59.     in eat.c:    seeoff(0)    - blind after eating rotten food
  60.     in mhitu.c:  seeoff(0)    - blinded by a glowing eye
  61.     in mhitu.c:  seeoff(1)    - swallowed
  62.     in mthrow.c: seeoff(0)    - hit by a cream pie.
  63.     in potion.c: seeoff(0)    - quaffing or sniffing a potion of blindness
  64.     in spell.c:  seeoff(0)    - due to a cursed spell book
  65.     in trap.c:   seeoff(1)    - fall through trap door
  66.  */
  67. void
  68. seeoff(mode)
  69. int mode;
  70. {        /* 1 to redo @, 0 to leave them */
  71.         /* 1 means misc movement, 0 means blindness */
  72.     register xchar x,y;
  73.     register struct rm *lev;
  74.  
  75.     if(u.udispl && mode){
  76.         u.udispl = 0;
  77.         levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy);
  78.     }
  79.     if(seehx) {
  80.         seehx = 0;
  81.     } else
  82.         if(!mode) {
  83.         for(x = u.ux-1; x < u.ux+2; x++)
  84.             for(y = u.uy-1; y < u.uy+2; y++) {
  85.             if(!isok(x, y)) continue;
  86.             lev = &levl[x][y];
  87.             if(MON_AT(x, y))
  88.                 unpmon(m_at(x,y));
  89.             if(!lev->lit && lev->scrsym == ROOM_SYM) {
  90.                 lev->seen = 0;
  91.                 atl(x, y, (char)STONE_SYM);
  92.             }
  93.             }
  94.         }
  95. }
  96.  
  97. #endif /* OVLB */
  98. #ifdef OVL2
  99.  
  100. STATIC_OVL int
  101. moverock() {
  102.     register xchar rx, ry;
  103.     register struct obj *otmp, *otmp2;
  104.     register struct trap *ttmp;
  105.     register struct    monst *mtmp;
  106.  
  107. #ifdef POLYSELF
  108.     if (passes_walls(uasmon)) return 0;
  109. #endif
  110.     while(otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) {
  111.         rx = u.ux+2*u.dx;
  112.         ry = u.uy+2*u.dy;
  113.         nomul(0);
  114. #ifdef POLYSELF
  115.         if (verysmall(uasmon)) {
  116.             pline("You're too small to push that boulder.");
  117.             goto cannot_push;
  118.         }
  119. #endif
  120.         if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
  121.             (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || (
  122. #ifdef REINCARNATION
  123.             dlevel != rogue_level &&
  124. #endif
  125.              (levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) &&
  126.             !sobj_at(BOULDER, rx, ry)) {
  127.             if(MON_AT(rx, ry)) {
  128.                 mtmp = m_at(rx,ry);
  129.                 if(canseemon(mtmp))
  130.                 pline("There's %s on the other side.",
  131.                       mon_nam(mtmp));
  132.                 else
  133.                 You("hear a monster behind the boulder.");
  134.                 if(flags.verbose)
  135.                 pline("Perhaps that's why you cannot move it.");
  136.                 goto cannot_push;
  137.             }
  138.             if(ttmp = t_at(rx,ry))
  139.                 switch(ttmp->ttyp) {
  140.                 case SPIKED_PIT:
  141.                 case PIT:
  142.                 You("push the boulder into a pit!");
  143.                 deltrap(ttmp);
  144.                 delobj(otmp);
  145.                 if(cansee(rx,ry)) newsym(rx,ry);
  146.                 else levl[rx][ry].seen = 0;
  147.                 if(flags.verbose)
  148.                     pline("It completely fills the pit!");
  149.                 continue;
  150.                 case TRAPDOOR:
  151.                 if(is_maze_lev
  152. #ifdef STRONGHOLD
  153.                     && (dlevel > stronghold_level)
  154. #endif
  155.                     ) break;
  156.                 pline("The boulder falls into and plugs a hole in the ground!");
  157.                 deltrap(ttmp);
  158.                 delobj(otmp);
  159.                 if(cansee(rx,ry)) newsym(rx,ry);
  160.                 else levl[rx][ry].seen = 0;
  161.                 continue;
  162.                 case LEVEL_TELEP:
  163.                 case TELEP_TRAP:
  164.                 You("push the boulder and suddenly it disappears!");
  165.                 rloco(otmp);
  166.                 continue;
  167.                 }
  168.             if(closed_door(rx, ry))
  169.                 goto nopushmsg;
  170.             if(is_pool(rx,ry)) {
  171. #ifdef STRONGHOLD
  172.                 if(levl[rx][ry].typ == DRAWBRIDGE_UP)
  173.                     levl[rx][ry].drawbridgemask |= DB_FLOOR;
  174.                 else
  175. #endif
  176.                     levl[rx][ry].typ = ROOM;
  177.                 mnewsym(rx,ry);
  178.                 if(!Blind) prl(rx,ry);
  179.                 You("push the boulder into the water.");
  180.                 if(flags.verbose && !Blind)
  181.                     pline("Now you can cross the water!");
  182.                 delobj(otmp);
  183.                 continue;
  184.             }
  185.                 /*
  186.                  * Re-link at top of fobj chain so that 
  187.                  * pile order is preserved when level is 
  188.                  * restored.
  189.                  */
  190.             if (otmp != fobj) {
  191.                 otmp2 = fobj;
  192.                 while (otmp2->nobj && otmp2->nobj != otmp) 
  193.                     otmp2 = otmp2->nobj;
  194.                 if (!otmp2->nobj)
  195.                     impossible("moverock: error in fobj chain");
  196.                 else {
  197.                     otmp2->nobj = otmp->nobj;    
  198.                     otmp->nobj = fobj;
  199.                     fobj = otmp;
  200.                 }
  201.             }
  202.             move_object(otmp, rx, ry);
  203.             /* pobj(otmp); */
  204.             if(cansee(rx,ry)) atl(rx,ry,otmp->olet);
  205.             newsym(u.ux+u.dx, u.uy+u.dy);
  206.  
  207.             {
  208. #ifdef LINT    /* static long lastmovetime; */
  209.             long lastmovetime;
  210.             lastmovetime = 0;
  211. #else
  212.             static long NEARDATA lastmovetime;
  213. #endif
  214.             /* note: this var contains garbage initially and
  215.                after a restore */
  216.             if(moves > lastmovetime+2 || moves < lastmovetime)
  217.             pline("With great effort you move the boulder.");
  218.             lastmovetime = moves;
  219.             }
  220.         } else {
  221. nopushmsg:
  222.             You("try to move the boulder, but in vain.");
  223.         cannot_push:
  224. #ifdef POLYSELF
  225.             if (throws_rocks(uasmon)) {
  226.             if(!flags.pickup)
  227.                 pline("However, you easily can push it aside.");
  228.             else
  229.                 pline("However, you easily can pick it up.");
  230.             break;
  231.             }
  232. #endif
  233.             if((!invent || inv_weight()+90 <= 0) &&
  234.             (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
  235.                     && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))
  236. #ifdef POLYSELF
  237.             || verysmall(uasmon)
  238. #endif
  239.                                     )
  240.             {
  241.             pline("However, you can squeeze yourself into a small opening.");
  242.             break;
  243.             } else
  244.             return (-1);
  245.         }
  246.     }
  247.     return (0);
  248. }
  249.  
  250. #endif /* OVL2 */
  251. #ifdef OVLB
  252.  
  253. void
  254. movobj(obj, ox, oy)
  255. register struct obj *obj;
  256. register xchar ox, oy;
  257. {
  258.     remove_object(obj);
  259.     if (cansee(obj->ox, obj->oy)) {
  260.         levl[obj->ox][obj->oy].seen = 0;
  261.         prl(obj->ox, obj->oy);
  262.     } else
  263.         newsym(obj->ox, obj->oy);
  264.     place_object(obj, ox, oy);
  265.     if (cansee(ox, oy)) {
  266.         levl[ox][oy].seen = 0;
  267.         prl(ox, oy);
  268.     } else
  269.         newsym(ox, oy);
  270. }
  271.  
  272. #ifdef SINKS
  273. STATIC_OVL
  274. void
  275. dosinkfall() {
  276.     register struct obj *obj;
  277.  
  278. # ifdef POLYSELF
  279.     if (is_floater(uasmon)) {
  280.         You("wobble unsteadily for a moment.");
  281.     } else {
  282. # endif
  283.         You("crash to the floor!");
  284.         losehp((rn1(10, 20 - (int)ACURR(A_CON))),
  285.             "fell onto a sink", NO_KILLER_PREFIX);
  286.         for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
  287.             if(obj->olet == WEAPON_SYM) {
  288.             You("fell on %s.",doname(obj));
  289.             losehp(rn2(3),"fell onto a sink", NO_KILLER_PREFIX);
  290.             }
  291. # ifdef POLYSELF
  292.     }
  293. # endif
  294.  
  295.     HLevitation = (HLevitation & ~TIMEOUT) + 1;
  296.     if(uleft && uleft->otyp == RIN_LEVITATION) {
  297.         obj = uleft;
  298.         Ring_off(obj);
  299.         off_msg(obj);
  300.     }
  301.     if(uright && uright->otyp == RIN_LEVITATION) {
  302.         obj = uright;
  303.         Ring_off(obj);
  304.         off_msg(obj);
  305.     }
  306.     if(uarmf && uarmf->otyp == LEVITATION_BOOTS) {
  307.         obj = uarmf;
  308.         (void)Boots_off();
  309.         off_msg(obj);
  310.     }
  311.     HLevitation--;
  312. }
  313. #endif
  314.  
  315. #endif /* OVLB */
  316. #ifdef OVL1
  317.  
  318. static boolean
  319. is_edge(x,y)
  320. register xchar x,y;
  321. /* return true if (x,y) is on the edge of a room
  322.  * we cannot rely on IS_DOOR(levl[x][y].typ) because some of the stronghold
  323.  * "rooms" are actually outside areas without doors
  324.  */
  325. {
  326.     register int roomno = inroom(x,y);
  327.  
  328.     if(roomno < 0) return FALSE;
  329.     return((x == rooms[roomno].lx - 1) || (x == rooms[roomno].hx + 1) ||
  330.            (y == rooms[roomno].ly - 1) || (y == rooms[roomno].hy + 1));
  331. }
  332.  
  333. #endif /* OVL1 */
  334. #ifdef OVLB
  335.  
  336. boolean
  337. may_dig(x,y)
  338. register xchar x,y;
  339. /* intended to be called only on ROCKs */
  340. {
  341. return (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE)));
  342. }
  343.  
  344. #endif /* OVLB */
  345. #ifdef OVL1
  346.  
  347. static boolean
  348. bad_rock(x,y)
  349. register xchar x,y;
  350. {
  351.     return(IS_ROCK(levl[x][y].typ)
  352. #ifdef POLYSELF
  353.             && !passes_walls(uasmon)
  354.             && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y))
  355. #endif
  356.     );
  357. }
  358.  
  359. void
  360. domove() {
  361.     register struct monst *mtmp;
  362.     register struct rm *tmpr,*ust;
  363.     register xchar x,y;
  364.     struct trap *trap;
  365.  
  366.     u_wipe_engr(rnd(5));
  367.  
  368.     if(inv_weight() > 0){
  369.         You("collapse under your load.");
  370.         nomul(0);
  371.         return;
  372.     }
  373.     if(u.uswallow) {
  374.         register xchar xx,yy;
  375.  
  376.         u.dx = u.dy = 0;
  377.         xx = u.ux;
  378.         yy = u.uy;
  379.         x = u.ux = u.ustuck->mx;
  380.         y = u.uy = u.ustuck->my;
  381.         if(xx != x || yy != y) newsym(xx,yy);
  382.         mtmp = u.ustuck;
  383.     } else {
  384.         x = u.ux + u.dx;
  385.         y = u.uy + u.dy;
  386.         if(Stunned || (Confusion && !rn2(5))) {
  387.             register int tries = 0;
  388.  
  389.             do {
  390.                 if(tries++ > 50) {
  391.                     nomul(0);
  392.                     return;
  393.                 }
  394.                 confdir();
  395.                 x = u.ux + u.dx;
  396.                 y = u.uy + u.dy;
  397.             } while(!isok(x, y) || bad_rock(x, y));
  398.         }
  399.         if(!isok(x, y)) {
  400.             nomul(0);
  401.             return;
  402.         }
  403.         if((trap = t_at(x, y)) && trap->tseen)
  404.             nomul(0);
  405.         if(u.ustuck && (x != u.ustuck->mx ||
  406.                 y != u.ustuck->my)) {
  407.             if(dist(u.ustuck->mx, u.ustuck->my) > 2) {
  408.             /* perhaps it fled (or was teleported or ... ) */
  409.                 u.ustuck = 0;
  410.             } else {
  411. #ifdef POLYSELF
  412.                 /* If polymorphed into a sticking monster,
  413.                  * u.ustuck means it's stuck to you, not you
  414.                  * to it.
  415.                  */
  416.                 if (sticks(uasmon)) {
  417.                     kludge("You release %s.",
  418.                         mon_nam(u.ustuck));
  419.                     u.ustuck = 0;
  420.                 } else {
  421. #endif
  422.                     kludge("You cannot escape from %s!",
  423.                         mon_nam(u.ustuck));
  424.                     nomul(0);
  425.                     return;
  426. #ifdef POLYSELF
  427.                 }
  428. #endif
  429.             }
  430.         }
  431.         mtmp = m_at(x,y);
  432.         if (mtmp) {
  433.             /* Don't attack if you're running */
  434.             if (flags.run && !mtmp->mimic &&
  435.                     (Blind ? Telepat :
  436.                      (!mtmp->minvis || See_invisible))) {
  437.                 nomul(0);
  438.                 flags.move = 0;
  439.                 return;
  440.             }
  441.         }
  442.     }
  443.  
  444.     u.ux0 = u.ux;
  445.     u.uy0 = u.uy;
  446.     tmpr = &levl[x][y];
  447.  
  448.     /* attack monster */
  449.     if(mtmp) {
  450.         nomul(0);
  451.         gethungry();
  452.         if(multi < 0) return;    /* we just fainted */
  453.  
  454.         /* try to attack; note that it might evade */
  455.         if(attack(mtmp)) return;
  456.     }
  457.  
  458.     /* not attacking an animal, so we try to move */
  459. #ifdef POLYSELF
  460.     if(!uasmon->mmove) {
  461.         You("are rooted %s.", Levitation ? "in place"
  462.             : "to the ground");
  463.         nomul(0);
  464.         return;
  465.     }
  466. #endif
  467.     if(u.utrap) {
  468.         if(u.utraptype == TT_PIT) {
  469.             if(flags.verbose)
  470.             Norep("You are still in a pit.");
  471.             u.utrap--;
  472.         } else if (u.utraptype == TT_WEB) {
  473.             if(flags.verbose)
  474.                 Norep("You are stuck to the web.");
  475.             u.utrap--;
  476.         } else {
  477.             if(flags.verbose)
  478.             Norep("You are caught in a bear trap.");
  479.             if((u.dx && u.dy) || !rn2(5)) u.utrap--;
  480.         }
  481.         return;
  482.     }
  483.     /* check for physical obstacles */
  484. #ifdef POLYSELF
  485.     if (!passes_walls(uasmon)) {
  486. #endif
  487. #ifdef STRONGHOLD
  488.         if(dlevel == stronghold_level && is_db_wall(x,y)) {
  489.             pline("The drawbridge is up!");
  490.             nomul(0);
  491.             return;
  492.         }
  493. #endif
  494.         if(closed_door(x, y)) {
  495. #ifdef POLYSELF
  496.         if(amorphous(uasmon))
  497.             You("ooze under the door.");
  498.         else {
  499. #endif
  500.             flags.move = 0;
  501.             if(x == u.ux || y == u.uy) {
  502.                 if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling)
  503.                 pline("Ouch!  You bump into a door.");
  504.                  else pline("That door is closed.");
  505.             }
  506.             nomul(0);
  507.             return;
  508. #ifdef POLYSELF
  509.         }
  510. #endif
  511.         }
  512. #ifdef POLYSELF
  513.     }
  514. #endif
  515.     ust = &levl[u.ux][u.uy];
  516.  
  517.     if(bad_rock(x,y) ||
  518.        (u.dx && u.dy
  519. #ifdef POLYSELF
  520.          && !passes_walls(uasmon)
  521. #endif
  522.          && ( (IS_DOOR(ust->typ) && block_entry(x, y)) ||
  523. #ifdef REINCARNATION
  524.             (IS_DOOR(tmpr->typ) &&
  525.              ((tmpr->doormask & ~D_BROKEN) 
  526.                || dlevel == rogue_level || block_door(x, y))
  527.                         )  
  528.              || (IS_DOOR(ust->typ) &&
  529.              ((ust->doormask & ~D_BROKEN) || dlevel == rogue_level)
  530.                         )
  531. #else
  532.             (IS_DOOR(tmpr->typ) &&
  533.              ((tmpr->doormask & ~D_BROKEN) || block_door(x, y))) ||
  534.             (IS_DOOR(ust->typ) && (ust->doormask & ~D_BROKEN))
  535. #endif
  536.             )
  537.        )) {
  538.         flags.move = 0;
  539.         nomul(0);
  540.         return;
  541.     }
  542.     if(moverock() < 0) return;
  543.     if(u.dx && u.dy && bad_rock(u.ux,y) &&
  544.                bad_rock(x,u.uy)) {
  545. #ifdef POLYSELF
  546.         if (bigmonst(uasmon)) {
  547.         Your("body is too large to fit through.");
  548.         nomul(0);
  549.         return;
  550.         }
  551. #endif
  552.         if (invent && inv_weight()+40 > 0) {
  553.         You("are carrying too much to get through.");
  554.         nomul(0);
  555.         return;
  556.         }
  557.     }
  558.     if(Punished &&
  559.        dist2(x, y, uchain->ox, uchain->oy) > 2) {
  560.         if(carried(uball)) {
  561.             movobj(uchain, u.ux, u.uy);
  562.             goto nodrag;
  563.         }
  564.  
  565.         if(dist2(x, y, uball->ox, uball->oy) < 3) {
  566.             /* leave ball, move chain under/over ball */
  567.             movobj(uchain, uball->ox, uball->oy);
  568.             goto nodrag;
  569.         }
  570.  
  571.         if(inv_weight() + (int)(uball->owt >> 1) > 0) {
  572.             You("cannot %sdrag the heavy iron ball.",
  573.             invent ? "carry all that and also " : "");
  574.             nomul(0);
  575.             return;
  576.         }
  577.  
  578.         movobj(uball, uchain->ox, uchain->oy);
  579.         movobj(uchain, u.ux, u.uy);
  580.         nomul(-2);
  581.         nomovemsg = "";
  582.     nodrag:    ;
  583.     }
  584. #ifdef POLYSELF
  585.     if (tunnels(uasmon) && !needspick(uasmon) && IS_ROCK(tmpr->typ)) {
  586.         static const char NEARDATA *digtxt;
  587.  
  588.         if(dig_pos.x != x || dig_pos.y != y
  589.             || dig_level != dlevel || dig_down) {
  590.             dig_down = FALSE;
  591.             dig_pos.x = x;
  592.             dig_pos.y = y;
  593.             dig_level = dlevel;
  594.             dig_effort = 30;
  595.             You("start chewing a hole in the rock.");
  596.             return;
  597.         } else if ((dig_effort += 30) < 100)  {
  598.             if(flags.verbose)
  599.             You("continue chewing the rock up.");
  600.             return;
  601.         } else {
  602.             if (IS_WALL(tmpr->typ)) {
  603.                 digtxt = "You chew a hole in the wall.";
  604.                 if(!is_maze_lev)
  605.                   tmpr->typ = DOOR;
  606.                 else
  607.                   tmpr->typ = ROOM;
  608.             } else if (tmpr->typ==SDOOR) {
  609.                 digtxt = "You chew through a secret door.";
  610.                 tmpr->typ = DOOR;
  611.                 if(!(tmpr->doormask & D_TRAPPED))
  612.                     tmpr->doormask = D_BROKEN;
  613.             } else {
  614.                 digtxt = "You chew a passage through the rock.";
  615.                 tmpr->typ = CORR;
  616.             }
  617.             mnewsym(x, y);
  618.             prl(x, y);
  619.             pline(digtxt);
  620.             if(IS_DOOR(tmpr->typ) && (tmpr->doormask & D_TRAPPED)) {
  621.                 b_trapped("door");
  622.                 tmpr->doormask = D_NODOOR;
  623.                 mnewsym(x, y);
  624.                 prl(x, y);
  625.             }
  626.             dig_level = -1;
  627.         }
  628.     }
  629. #endif
  630.     u.ux += u.dx;
  631.     u.uy += u.dy;
  632.     reset_occupations();
  633.     if(flags.run) {
  634.         if(IS_DOOR(tmpr->typ) ||
  635. #ifdef POLYSELF
  636.         (IS_ROCK(tmpr->typ)) ||
  637. #endif
  638.         (xupstair == u.ux && yupstair == u.uy) ||
  639.         (xdnstair == u.ux && ydnstair == u.uy)
  640. #ifdef STRONGHOLD
  641.         || (xupladder == u.ux && yupladder == u.uy)
  642.         || (xdnladder == u.ux && ydnladder == u.uy)
  643. #endif
  644. #ifdef FOUNTAINS
  645.         || IS_FOUNTAIN(tmpr->typ)
  646. #endif
  647. #ifdef THRONES
  648.         || IS_THRONE(tmpr->typ)
  649. #endif
  650. #ifdef SINKS
  651.         || IS_SINK(tmpr->typ)
  652. #endif
  653. #ifdef ALTARS
  654.         || IS_ALTAR(tmpr->typ)
  655. #endif
  656.         )
  657.             nomul(0);
  658.     }
  659. #ifdef POLYSELF
  660.     if (hides_under(uasmon))
  661.         u.uundetected = (OBJ_AT(u.ux, u.uy) || levl[u.ux][u.uy].gmask);
  662.     else if (u.dx || u.dy) { /* piercer */
  663.         if (u.usym == S_MIMIC_DEF)
  664.         u.usym = S_MIMIC;
  665.         u.uundetected = 0;
  666.     }
  667. #endif
  668.  
  669. /*
  670.     if(u.udispl) {
  671.         u.udispl = 0;
  672.         newsym(u.ux0,u.uy0);
  673.     }
  674. */
  675.     if(!Blind) {
  676.         register xchar backx = u.ux0 - u.dx;   /* one step beyond old pos */
  677.         register xchar backy = u.uy0 - u.dy;
  678.         register xchar frontx = u.ux + u.dx;   /* one step beyond new pos */
  679.         register xchar fronty = u.uy + u.dy;
  680.         register boolean newedge = is_edge(u.ux,u.uy);
  681.         register boolean oldedge = is_edge(u.ux0,u.uy0);
  682.  
  683.         /* ust is old position, tmpr is new position */
  684.         if(oldedge && newedge && inroom(u.ux0,u.uy0) == inroom(u.ux,u.uy)) {
  685.         /* moving along wall */
  686.         nose1(backx,backy);
  687.         prl1(frontx,fronty);
  688.  
  689.         } else if(oldedge || newedge) {
  690.         if(isok(backx,backy) && levl[backx][backy].lit)
  691.             setsee();
  692.         else
  693.             nose1(backx,backy);
  694.  
  695.         if(isok(frontx,fronty) && levl[frontx][fronty].lit)
  696.             setsee();
  697.         else {
  698.             prl1(frontx,fronty);
  699.             prl1(u.ux,u.uy);    /* make sure side walls are seen */
  700.         }
  701.  
  702.         } else if(!tmpr->lit) {
  703.         /* we haven't crossed an edge, so old & new are both light or
  704.          * both dark.  if both light, we need do nothing.
  705.          */
  706.         nose1(backx,backy);
  707.         prl1(frontx,fronty);
  708.         }
  709.  
  710.     } else {
  711.         pru();
  712.     }
  713. #ifdef WALKIES
  714.     check_leash(u.ux0,u.uy0);
  715. #endif
  716.     if(u.ux0 != u.ux || u.uy0 != u.uy) u.umoved = TRUE;
  717.     spoteffects();
  718. }
  719.  
  720. #endif /* OVL1 */
  721. #ifdef OVL2
  722.  
  723. void
  724. spoteffects()
  725. {
  726.     register struct trap *trap;
  727.  
  728.     if(is_pool(u.ux,u.uy) && !(Levitation || Wwalking
  729. #ifdef POLYSELF
  730.         || is_flyer(uasmon)
  731. #endif
  732.         ))
  733.         drown();    /* not necessarily fatal */
  734.     else {
  735.         (void) inshop();
  736. #ifdef SINKS
  737.         if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
  738.             dosinkfall();
  739. #endif
  740.         if(!flags.nopick &&
  741.            (OBJ_AT(u.ux, u.uy) || levl[u.ux][u.uy].gmask))
  742.             pickup(1);
  743.         else read_engr_at(u.ux,u.uy);
  744.         if(trap = t_at(u.ux,u.uy))
  745.             dotrap(trap);    /* fall into pit, arrow trap, etc. */
  746.     }
  747.  
  748. }
  749.  
  750. #endif /* OVL2 */
  751. #ifdef OVLB
  752.  
  753. int
  754. dopickup() {
  755.     /* uswallow case added by GAN 01/29/87 */
  756.     if(u.uswallow)  {
  757.         if (is_animal(u.ustuck->data)) {
  758.             You("pick up %s's tongue.", mon_nam(u.ustuck));
  759.             pline("But it's kind of slimy, so you drop it.");
  760.         } else
  761.             You("don't %s anything in here to pick up.",
  762.               Blind ? "feel" : "see");
  763.         return(1);
  764.     }
  765.     if(!OBJ_AT(u.ux, u.uy) && levl[u.ux][u.uy].gmask == 0) {
  766.         pline("There is nothing here to pick up.");
  767.         return(0);
  768.     }
  769.     if(Levitation) {
  770.         You("cannot reach the floor.");
  771.         return(1);
  772.     }
  773.     pickup(0);
  774.     return(1);
  775. }
  776.  
  777. #endif /* OVLB */
  778. #ifdef OVL2
  779.  
  780. /* stop running if we see something interesting */
  781. /* turn around a corner if that is the only way we can proceed */
  782. /* do not turn left or right twice */
  783. void
  784. lookaround() {
  785.     register int x, y, i, x0, y0, m0, i0 = 9, corrct = 0, noturn = 0;
  786.     register struct monst *mtmp;
  787. #if defined(LINT) || defined(__GNULINT__)
  788.     /* suppress "used before set" message */
  789.     x0 = y0 = m0 = 0;
  790. #endif
  791.     if(Blind || flags.run == 0) return;
  792.     for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) {
  793.         if(!isok(x,y)) continue;
  794. #ifdef POLYSELF
  795.         if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue;
  796. #endif
  797.         if(x == u.ux && y == u.uy) continue;
  798.         if((mtmp = m_at(x,y)) && !mtmp->mimic &&
  799.             (!mtmp->minvis || See_invisible) && !mtmp->mundetected) {
  800.             if((flags.run != 1 && !mtmp->mtame)
  801.                     || (x == u.ux+u.dx && y == u.uy+u.dy))
  802.                 goto stop;
  803.         }
  804.         if(levl[x][y].typ == STONE) continue;
  805.         if(x == u.ux-u.dx && y == u.uy-u.dy) continue;
  806.         {
  807.         register uchar sym = levl[x][y].scrsym;
  808.  
  809.         if (IS_ROCK(levl[x][y].typ) ||
  810.            (sym == ROOM_SYM && !IS_DOOR(levl[x][y].typ)))
  811.              continue;
  812.         else if (sym == CLOSED_DOOR_SYM) {
  813.             if(x != u.ux && y != u.uy) continue;
  814.             if(flags.run != 1) goto stop;
  815.             goto bcorr;
  816.         } else if (sym == CORR_SYM) {
  817.         bcorr:
  818.             if(levl[u.ux][u.uy].typ != ROOM) {
  819.                 if(flags.run == 1 || flags.run == 3) {
  820.                 i = dist2(x,y,u.ux+u.dx,u.uy+u.dy);
  821.                 if(i > 2) continue;
  822.                 if(corrct == 1 && dist2(x,y,x0,y0) != 1)
  823.                     noturn = 1;
  824.                 if(i < i0) {
  825.                     i0 = i;
  826.                     x0 = x;
  827.                     y0 = y;
  828.                     m0 = mtmp ? 1 : 0;
  829.                 }
  830.                 }
  831.                 corrct++;
  832.             }
  833.             continue;
  834.         } else if (sym == TRAP_SYM) {
  835.             if(flags.run == 1) goto bcorr;    /* if you must */
  836.             if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  837.             continue;
  838.         } else if (sym == POOL_SYM) {
  839.             /* pools only stop you if directly in front, and stop
  840.              * you even if you are running
  841.              */
  842.             if(!Levitation &&
  843. #ifdef POLYSELF
  844.                 !is_flyer(uasmon) &&
  845. #endif
  846.                 /* No Wwalking check; otherwise they'd be able
  847.                  * to test boots by trying to SHIFT-direction
  848.                  * into a pool and seeing if the game allowed it
  849.                  */
  850.                 x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  851.             continue;
  852.         } else {        /* e.g. objects or trap or stairs */
  853.             if(flags.run == 1) goto bcorr;
  854.             if(mtmp) continue;        /* d */
  855.         }
  856.         stop:
  857.             nomul(0);
  858.             return;
  859.         }
  860.     }
  861.     if(corrct > 1 && flags.run == 2) goto stop;
  862.     if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
  863.         (corrct == 1 || (corrct == 2 && i0 == 1))) {
  864.         /* make sure that we do not turn too far */
  865.         if(i0 == 2) {
  866.             if(u.dx == y0-u.uy && u.dy == u.ux-x0)
  867.             i = 2;        /* straight turn right */
  868.             else
  869.             i = -2;        /* straight turn left */
  870.         } else if(u.dx && u.dy) {
  871.             if((u.dx == u.dy && y0 == u.uy) ||
  872.             (u.dx != u.dy && y0 != u.uy))
  873.             i = -1;        /* half turn left */
  874.             else
  875.             i = 1;        /* half turn right */
  876.         } else {
  877.             if((x0-u.ux == y0-u.uy && !u.dy) ||
  878.             (x0-u.ux != y0-u.uy && u.dy))
  879.             i = 1;        /* half turn right */
  880.             else
  881.             i = -1;        /* half turn left */
  882.         }
  883.         i += u.last_str_turn;
  884.         if(i <= 2 && i >= -2) {
  885.             u.last_str_turn = i;
  886.             u.dx = x0-u.ux, u.dy = y0-u.uy;
  887.         }
  888.     }
  889. }
  890.  
  891. /* something like lookaround, but we are not running */
  892. /* react only to monsters that might hit us */
  893. int
  894. monster_nearby() {
  895.     register int x,y;
  896.     register struct monst *mtmp;
  897.  
  898.     if(!Blind)
  899.     for(x = u.ux-1; x <= u.ux+1; x++)
  900.         for(y = u.uy-1; y <= u.uy+1; y++) {
  901.         if(!isok(x,y)) continue;
  902.         if(x == u.ux && y == u.uy) continue;
  903.         if((mtmp = m_at(x,y)) && !mtmp->mimic &&
  904.            !mtmp->mtame && !mtmp->mpeaceful &&
  905.            !noattacks(mtmp->data) &&
  906.            mtmp->mcanmove && !mtmp->msleep &&  /* aplvax!jcn */
  907.            (!mtmp->minvis || See_invisible) &&
  908.            !onscary(u.ux, u.uy, mtmp))
  909.             return(1);
  910.     }
  911.     return(0);
  912. }
  913.  
  914. #endif /* OVL2 */
  915. #ifdef OVL0
  916.  
  917. int
  918. cansee(x,y)
  919. xchar x,y;
  920. {
  921.     if(Blind || (u.uswallow && (x != u.ux || y != u.uy))) return(0);
  922.     if(IS_ROCK(levl[x][y].typ) && levl[u.ux][u.uy].typ == CORR &&
  923.                 !MON_AT(x, y) && !levl[u.ux][u.uy].lit)
  924.         return(0);
  925.     if(dist(x,y) < 3) return(1);
  926.     if(levl[x][y].lit &&
  927.         ((seelx <= x && x <= seehx && seely <= y && y <= seehy) ||
  928.         (seelx2 <= x && x <= seehx2 && seely2 <= y && y <= seehy2)))
  929.         return(1);
  930.     return(0);
  931. }
  932.  
  933. #endif /* OVL0 */
  934. #ifdef OVL1
  935.  
  936. int
  937. sgn(a)
  938.     register int a;
  939. {
  940.     return((a > 0) ? 1 : (a == 0) ? 0 : -1);
  941. }
  942.  
  943. #endif /* OVL1 */
  944. #ifdef OVL2
  945.  
  946. void
  947. getcorners(lx1,hx1,ly1,hy1,lx2,hx2,ly2,hy2)
  948. xchar *lx1,*hx1,*ly1,*hy1,*lx2,*hx2,*ly2,*hy2;
  949. /* return corners of one or two rooms player is in, so we can tell what areas
  950.  * can be seen, or otherwise affected by room-specific things.  (two rooms are
  951.  * possible when in a doorway of the stronghold)
  952.  * the player is already known to be in at least one room
  953.  */
  954. {
  955.     register int uroom1,uroom2;
  956.     register xchar ux,uy;
  957.  
  958.     uroom1 = inroom(u.ux,u.uy);
  959.     *lx1 = rooms[uroom1].lx - 1;
  960.     *hx1 = rooms[uroom1].hx + 1;
  961.     *ly1 = rooms[uroom1].ly - 1;
  962.     *hy1 = rooms[uroom1].hy + 1;
  963.  
  964.     if(!IS_DOOR(levl[u.ux][u.uy].typ)) {
  965.         *lx2 = 1;
  966.         *hx2 = 0;
  967.         *ly2 = 1;
  968.         *hy2 = 0;
  969.     } else {
  970.         for(ux = u.ux-1; ux <= u.ux+1; ux++)
  971.             for(uy = u.uy-1; uy <= u.uy+1; uy++) {
  972.                 if(!isok(ux,uy)) continue;
  973.                 if(IS_ROCK(levl[ux][uy].typ) ||
  974.                     IS_DOOR(levl[ux][uy].typ)) continue;
  975.                 /* might have side-by-side walls, in which case
  976.                  * should only be able to see one room */
  977.                 uroom2 = inroom(ux,uy);
  978.                 if(uroom2 >= 0 && uroom2 != uroom1 && 
  979.                    rooms[uroom2].rlit) {
  980.                     *lx2 = rooms[uroom2].lx - 1;
  981.                     *ly2 = rooms[uroom2].ly - 1;
  982.                     *hx2 = rooms[uroom2].hx + 1;
  983.                     *hy2 = rooms[uroom2].hy + 1;
  984.                     return;
  985.                 }
  986.             }
  987.         *lx2 = 1;
  988.         *hx2 = 0;
  989.         *ly2 = 1;
  990.         *hy2 = 0;
  991.     }
  992. }
  993.  
  994. #endif /* OVL2 */
  995. #ifdef OVL1
  996.  
  997. void
  998. setsee() {
  999.     register int x, y;
  1000.  
  1001.     if(Blind) {
  1002.         pru();
  1003.         return;
  1004.     }
  1005.     if(!levl[u.ux][u.uy].lit) {
  1006.         seelx = u.ux-1;
  1007.         seehx = u.ux+1;
  1008.         seely = u.uy-1;
  1009.         seehy = u.uy+1;
  1010.         seelx2 = seely2 = 1;
  1011.         seehx2 = seehy2 = 0;
  1012.     } else {
  1013.         getcorners(&seelx,&seehx,&seely,&seehy,
  1014.                &seelx2,&seehx2,&seely2,&seehy2);
  1015.     }
  1016.     for(y = seely; y <= seehy; y++)
  1017.         for(x = seelx; x <= seehx; x++) {
  1018.             prl(x,y);
  1019.     }
  1020.     for(y = seely2; y <= seehy2; y++)
  1021.         for(x = seelx2; x <= seehx2; x++) {
  1022.             prl(x,y);
  1023.     }
  1024.     if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */
  1025.     else {
  1026.         if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1);
  1027.         if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1);
  1028.         if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y);
  1029.         if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y);
  1030.     }
  1031. }
  1032.  
  1033. #endif /* OVL1 */
  1034. #ifdef OVL2
  1035.  
  1036. void
  1037. nomul(nval)
  1038.     register int nval;
  1039. {
  1040.     if(multi < nval) return;    /* This is a bug fix by ab@unido */
  1041.     multi = nval;
  1042.     flags.mv = flags.run = 0;
  1043. }
  1044.  
  1045. #endif /* OVL2 */
  1046. #ifdef OVL1
  1047.  
  1048. void
  1049. losehp(n, knam, k_format)
  1050. register int n;
  1051. register const char *knam;
  1052. boolean k_format;
  1053. {
  1054. #ifdef POLYSELF
  1055.     if (u.mtimedone) {
  1056.         u.mh -= n;
  1057.         if (u.mhmax < u.mh) u.mhmax = u.mh;
  1058.         flags.botl = 1;
  1059.         if (u.mh < 1) rehumanize();
  1060.         return;
  1061.     }
  1062. #endif
  1063.     u.uhp -= n;
  1064.     if(u.uhp > u.uhpmax)
  1065.         u.uhpmax = u.uhp;    /* perhaps n was negative */
  1066.     flags.botl = 1;
  1067.     if(u.uhp < 1) {
  1068.         killer_format = k_format;
  1069.         killer = knam;        /* the thing that killed you */
  1070.         You("die...");
  1071.         done(DIED);
  1072.     } else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){
  1073.         wailmsg = moves;
  1074.         if(index("WEV", pl_character[0])) {
  1075.             if (u.uhp == 1)
  1076.                 pline("%s is about to die.", pl_character);
  1077.             else if (4 <= (!!(HTeleportation & INTRINSIC)) +
  1078.                     (!!(HSee_invisible & INTRINSIC)) +
  1079.                     (!!(HPoison_resistance & INTRINSIC)) +
  1080.                     (!!(HCold_resistance & INTRINSIC)) +
  1081.                     (!!(HShock_resistance & INTRINSIC)) +
  1082.                     (!!(HFire_resistance & INTRINSIC)) +
  1083.                     (!!(HSleep_resistance & INTRINSIC)) +
  1084.                     (!!(HDisint_resistance & INTRINSIC)) +
  1085.                     (!!(HTeleport_control & INTRINSIC)) +
  1086.                     (!!(Stealth & INTRINSIC)) +
  1087.                     (!!(Fast & INTRINSIC)) +
  1088.                     (!!(HInvis & INTRINSIC)))
  1089.                 pline("%s, all your powers will be lost...",
  1090.                     pl_character);
  1091.             else
  1092.                 pline("%s, your life force is running out.",
  1093.                     pl_character);
  1094.         } else {
  1095.             if(u.uhp == 1)
  1096.                 You("hear the wailing of the Banshee...");
  1097.             else
  1098.                 You("hear the howling of the CwnAnnwn...");
  1099.         }
  1100.     }
  1101. }
  1102.  
  1103. int
  1104. weight_cap() {
  1105.     register int carrcap;
  1106.  
  1107. #ifdef HARD
  1108.     carrcap = 5 * (((ACURR(A_STR) > 18) ? 20 : ACURR(A_STR)) + u.ulevel);
  1109. #else
  1110.     carrcap = 5 * u.ulevel;      /* New strength stewr 870807 */
  1111.     if (ACURR(A_STR) < 19) carrcap += 5 * ACURR(A_STR);
  1112.     if (ACURR(A_STR) > 18) carrcap += ACURR(A_STR) - 18 + 90;
  1113.     if (ACURR(A_STR) > 68) carrcap += ACURR(A_STR) - 68;
  1114.     if (ACURR(A_STR) > 93) carrcap += ACURR(A_STR) - 93;
  1115.     if (ACURR(A_STR) > 108) carrcap += 2 * (ACURR(A_STR) - 108);
  1116.     if (ACURR(A_STR) > 113) carrcap += 5 * (ACURR(A_STR) - 113);
  1117.     if (ACURR(A_STR) == 118) carrcap += 100;
  1118. #endif
  1119. #ifdef POLYSELF
  1120.     if (u.mtimedone) {
  1121.         /* consistent with can_carry() in mon.c */
  1122.         if (u.usym==S_NYMPH) carrcap = MAX_CARR_CAP;
  1123.         else if (!uasmon->cwt)
  1124.             carrcap = (carrcap * uasmon->mlevel * 6)/45;
  1125.         else if (!strongmonst(uasmon)
  1126.             || (strongmonst(uasmon) && (uasmon->cwt > 45)))
  1127.             carrcap = (carrcap * uasmon->cwt / 45);
  1128.     }
  1129. #endif
  1130.     if(Levitation)             /* pugh@cornell */
  1131.         carrcap = MAX_CARR_CAP;
  1132.     else {
  1133.         if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
  1134.         if(Wounded_legs & LEFT_SIDE) carrcap -= 10;
  1135.         if(Wounded_legs & RIGHT_SIDE) carrcap -= 10;
  1136.     }
  1137.     return(carrcap);
  1138. }
  1139.  
  1140. int
  1141. inv_weight() {
  1142.     register struct obj *otmp = invent;
  1143. #ifdef LINT    /* long to int conversion */
  1144.     register int wt = 0;
  1145. #else
  1146.     register int wt = (int)((u.ugold + 500L)/1000L);
  1147. #endif /* LINT */
  1148.     while(otmp){
  1149. #ifdef POLYSELF
  1150.         if (otmp->otyp != BOULDER || !throws_rocks(uasmon))
  1151. #endif
  1152.             wt += otmp->owt;
  1153.         otmp = otmp->nobj;
  1154.     }
  1155.     return(wt - weight_cap());
  1156. }
  1157.  
  1158. #endif /* OVL1 */
  1159. #ifdef OVLB
  1160.  
  1161. int
  1162. inv_cnt() {
  1163.     register struct obj *otmp = invent;
  1164.     register int ct = 0;
  1165.  
  1166.     while(otmp){
  1167.         ct++;
  1168.         otmp = otmp->nobj;
  1169.     }
  1170.     return(ct);
  1171. }
  1172.  
  1173. int
  1174. identify(otmp)        /* also called by newmail() */
  1175.     register struct obj *otmp;
  1176. {
  1177.     makeknown(otmp->otyp);
  1178.     otmp->known = otmp->dknown = otmp->bknown = 1;
  1179.     prinv(otmp);
  1180.     return(1);
  1181. }
  1182.  
  1183. #ifdef STUPID_CPP    /* otherwise these functions are macros in hack.h */
  1184. char
  1185. yn() {
  1186.     return(yn_function(ynchars, 'n'));
  1187. }
  1188.  
  1189. char
  1190. ynq() {
  1191.     return(yn_function(ynqchars, 'q'));
  1192. }
  1193.  
  1194. char
  1195. ynaq() {
  1196.     return(yn_function(ynaqchars, 'y'));
  1197. }
  1198.  
  1199. char
  1200. nyaq() {
  1201.     return(yn_function(nyaqchars, 'n'));
  1202. }
  1203.  
  1204. int
  1205. max(a,b) int a,b; {
  1206.     return((a > b) ? a : b);
  1207. }
  1208.  
  1209. int
  1210. min(a,b) int a,b; {
  1211.     return((a < b) ? a : b);
  1212. }
  1213.  
  1214. char *
  1215. plur(x) long x; {
  1216.     return((x == 1L) ? "" : "s");
  1217. }
  1218.  
  1219. void
  1220. makeknown(x) unsigned x; {
  1221.     objects[x].oc_name_known = 1;
  1222. }
  1223. #endif /* STUPID_CPP */
  1224.  
  1225. #endif /* OVLB */
  1226.